#视图文件
from django.shortcuts import render,redirect
from django.http import HttpResponse
# 通用类视图
from django.views import View
# 导入数据模型ArticlePost
from .models import ArticlePost
# 引入User模型
from django.contrib.auth.models import User
from .forms import ArticlePostForm
from django.contrib.auth.decorators import login_required
# 引入分页模块
from django.core.paginator import Paginator
# 引入 Q 对象
from django.db.models import Q
from comment.models import Comment
from comment.forms import CommentForm
from .models import ArticleColumn
# 引入markdown模块
import markdown

# Create your views here.
#视图函数
#文章列表
def article_list(request):
    # 根据GET请求中查询条件
    search = request.GET.get('search')
    order = request.GET.get('order')
    tag = request.GET.get('tag')  # 获取标签参数
    column = request.GET.get('column')
        # 初始化查询集
    article_list = ArticlePost.objects.all()
    # 用户搜索过滤
    if search:
        if order == 'total_views':
            # 用 Q对象 进行联合搜索
            article_list = ArticlePost.objects.filter(
                Q(title__icontains=search) |
                Q(body__icontains=search) |
                Q(tags__name__icontains=search)  # 添加标签搜索
            ).order_by('-total_views')
        else:
            article_list = ArticlePost.objects.filter(
                Q(title__icontains=search) |
                Q(body__icontains=search) |
                Q(tags__name__icontains=search)  # 添加标签搜索
            )
    else:
        # 将 search 参数重置为空
        search = ''
        if order == 'total_views':
            article_list = ArticlePost.objects.all().order_by('-total_views')
        else:
            article_list = ArticlePost.objects.all()

        # 栏目查询集
    if column is not None and column.isdigit():
        article_list = article_list.filter(column=column)

    # 标签查询集
    if tag and tag != 'None':
        article_list = article_list.filter(tags__name__in=[tag])

        # 查询集排序
    if order == 'total_views':
        article_list = article_list.order_by('-total_views')

    paginator = Paginator(article_list, 3)
    page = request.GET.get('page')
    articles = paginator.get_page(page)
    
    # 增加 search 到 context
    # 需要传递给模板（templates）的对象
    context = {
        'articles': articles,
        'order': order,
        'search': search,
        'column': column,
        'tag': tag,
    }
    
    
    return render(request, 'article/list.html', context)

# 文章详情
# 评论模块需要在文章详情页面展示，所以必须把评论模块的上下文也传递到模板中
def article_detail(request, id):
    # 取出相应的文章
    article = ArticlePost.objects.get(id=id)
        # 引入评论表单
    comment_form = CommentForm()
    # 取出文章评论
    comments = Comment.objects.filter(article=id)
    # 浏览量 +1,update_fields=[]指定了数据库只更新total_views字段，优化执行效率。
    # 只有当用户不是作者本人时才增加浏览量
    if request.user != article.author:
        article.total_views += 1
        article.save(update_fields=['total_views'])
    
    # 将markdown语法渲染成html样式
    md = markdown.Markdown(
        extensions=[
        'markdown.extensions.extra',
        'markdown.extensions.codehilite',
        'markdown.extensions.toc',
        ]
    )
    #onvert()方法将正文渲染为html页面
    article.body = md.convert(article.body)
    # 需要传递给模板的对象
    # 新增了md.toc对象,添加comments上下文
    context = { 'article': article, 'toc': md.toc, 'comment_form': comment_form,'comments': comments, # 添加评论列表到上下文
 }
    # 载入模板，并返回context对象
    return render(request, 'article/detail.html', context)


# 写文章的视图
# 检查登录
@login_required(login_url='/accounts/login/')
def article_create(request):
 
    # 判断用户是否提交数据
    if request.method == "POST":
        # 将提交的数据赋值到表单实例中
                # 增加 request.FILES
        article_post_form = ArticlePostForm(request.POST, request.FILES)
        # 判断提交的数据是否满足模型的要求
        if article_post_form.is_valid():
            # 保存数据，但暂时不提交到数据库中
            new_article = article_post_form.save(commit=False)
            column_id = request.POST.get('column', None)

            if column_id and column_id != 'none':
                try:
                    new_article.column = ArticleColumn.objects.get(id=column_id)
                except ArticleColumn.DoesNotExist:
                    return HttpResponse("栏目不存在，请重新选择。")
            else:
                # 设置默认栏目为“TheGreat”
                try:
                    new_article.column = ArticleColumn.objects.get(title='TheGreat')
                except ArticleColumn.DoesNotExist:
                    return HttpResponse("默认栏目不存在，请联系管理员。")

            # 指定数据库中 id=1 的用户为作者
            # 如果你进行过删除数据表的操作，可能会找不到id=1的用户
            # 此时请重新创建用户，并传入此用户的id
            # new_article.author = User.objects.get(id=1)
                   # 指定目前登录的用户为作者
            new_article.author = User.objects.get(id=request.user.id)
            # 将新文章保存到数据库中
            new_article.save()
            # 新增代码，保存 tags 的多对多关系
            article_post_form.save_m2m()
            # 完成后返回到文章列表
            return redirect("article:article_list")
        # 如果数据不合法，返回错误信息
        else:
            return HttpResponse(f"表单内容有误，请重新填写。错误信息: {article_post_form.errors.as_json()}")
            # return HttpResponse("表单内容有误，请重新填写。")
            
    # 如果用户请求获取数据
    else:
        # 创建表单类实例
        article_post_form = ArticlePostForm()
        columns = ArticleColumn.objects.all()
        # 赋值上下文
        context = { 'article_post_form': article_post_form, 'columns': columns }
        # 返回模板
        return render(request, 'article/create.html', context)
    
# 删文章
def article_safe_delete(request, id):
    if request.method == 'POST':
        article = ArticlePost.objects.get(id=id)
        article.delete()
        return redirect("article:article_list")
    else:
        return HttpResponse("仅允许post请求")

# 更新文章
# 提醒用户登录,login_required装饰器过滤未登录的用户
@login_required(login_url='/accounts/login/')
def article_update(request, id):
    """
    更新文章的视图函数
    通过POST方法提交表单，更新titile、body字段
    GET方法进入初始表单页面
    id： 文章的 id
    """

    # 获取需要修改的具体文章对象
    article = ArticlePost.objects.get(id=id)
    # 过滤非作者的用户,if语句过滤已登录、但非作者本人的用户
    if request.user != article.author:
        return HttpResponse("抱歉，你无权修改这篇文章。")
    # 判断用户是否为 POST 提交表单数据
    if request.method == "POST":
        article_post_form = ArticlePostForm(data=request.POST, instance=article)
        if article_post_form.is_valid():
            article = article_post_form.save(commit=False)
            column_id = request.POST.get('column', None)
            if column_id and column_id != 'none':
                try:
                    article.column = ArticleColumn.objects.get(id=column_id)
                except ArticleColumn.DoesNotExist:
                    return HttpResponse("栏目不存在，请重新选择。")
            else:
                article.column = None
            
            article.save()
            article_post_form.save_m2m()
            return redirect("article:article_detail", id=id)
        else:
            errors = article_post_form.errors.as_json()
            return HttpResponse(f"表单内容有误，请重新填写。错误信息: {errors}")

    else:
        article_post_form = ArticlePostForm(instance=article)
        columns = ArticleColumn.objects.all()
        context = { 
            'article': article, 
            'article_post_form': article_post_form,
            'columns': columns,
        }
        return render(request, 'article/update.html', context)
    
# 点赞数 +1
class IncreaseLikesView(View):
    def post(self, request, *args, **kwargs):
        article = ArticlePost.objects.get(id=kwargs.get('id'))
        article.likes += 1
        article.save()
        return HttpResponse('success')